// std::bind 详解
// std::bind 是 C++11 引入的一个强大的函数适配器，它允许我们创建新的可调用对象，通过绑定现有函数、成员函数或函数对象的部分或全部参数。

// 基本语法
auto bound_function = std::bind(callable, arg1, arg2, ..., argN);
// callable 是要绑定的函数、函数对象或成员函数指针
// arg1, arg2, ..., argN 是要绑定的参数或占位符

// 主要用途
// 1. 参数绑定
// 将函数的某些参数固定为特定值：
int subtract(int a, int b)
{
    return a - b;
}

// 创建一个新函数，第一个参数固定为10
auto subtract_from_10 = std::bind(subtract, 10, std::placeholders::_1);
int result = subtract_from_10(5); // 等价于 subtract(10, 5)，结果为5

// 2. 参数重排序
// 改变参数的顺序：
int divide(int a, int b)
{
    return a / b;
}

// 交换参数顺序
// filp_divide的10,用作divide函数的第二个参数,20用作divide函数的第一个参数
auto flip_divide = std::bind(divide, std::placeholders::_2, std::placeholders::_1);
int result = flip_divide(10, 20); // 等价于 divide(20, 10)，结果为2

// 3. 绑定成员函数
// 将成员函数与对象实例绑定：
class Calculator
{
public:
    int add(int a, int b) { return a + b; }
};

Calculator calc;
// 绑定成员函数和对象
auto add_func = std::bind(&Calculator::add, &calc, std::placeholders::_1, std::placeholders::_2);
int sum = add_func(5, 3); // 等价于 calc.add(5, 3)，结果为8

// 4. 减少参数数量
// 创建接受更少参数的函数：
void log(std::string level, std::string message)
{
    std::cout << "[" << level << "] " << message << std::endl;
}

// 创建只接受消息的错误日志函数
auto log_error = std::bind(log, "ERROR", std::placeholders::_1);
log_error("Disk full"); // 输出: [ERROR] Disk full

// 占位符
// std::placeholders 命名空间提供了一系列占位符：
// _1, _2, _3, ... 分别表示调用绑定函数时的第1个、第2个、第3个参数
// 使用多个占位符
auto complex_bind = std::bind(some_func, std::placeholders::_2,
                              std::placeholders::_1, 42, std::placeholders::_3);
// 调用 complex_bind(a, b, c) 等价于调用 some_func(b, a, 42, c)
